package database;

import java.io.IOException;

public class BufferManager {
	BufferPool pool;
	StorageManager storageManager;
	
	public BufferManager(int sizepool,String dbName) {
		pool = new BufferPool(sizepool);
		storageManager = new StorageManager(dbName); 
	}
	
	
	public void saveSchema(Table t, Object[][] tableSchema){
		storageManager.saveSchema(t,tableSchema);
		
	}
	
	
	public String addData(Record record, Table table){		// returns true if the data was added to the buffer false otherwise.
		String returnString = "";
		boolean isLastPage = pool.isLastPageOfTable(table);
		if(isLastPage){		// the last page is already in the buffer
				Page page = pool.getLastPageOfTable(table);
				if(record.size() < pool.freePool){	// there is enough space in the buffer to put the new record
					if( record.size() < page.freeSpace ){ // the new entry is added to the last page.
						returnString = page.addRecord(record);
						pool.sizePool += record.size();
						pool.freePool -= record.size();
					}
					else	//we add a new page to the table with the new record
						returnString = pool.addPage(record,table);
				}
				else{  // there isn't enough space in the pool
					int size;
					if(page.freeSpace > record.size()) 
						size = page.size() + record.size();
					else 
						size = record.size();
					
					while(pool.freePool < size ){			// we free some space until there is enough to put the page where the record will be stored.
						Page freepage = pool.freeSpace(page); //we free space without removing 'page'
						storageManager.store(freepage);
					}
					
					returnString = page.addRecord(record);
					pool.sizePool += record.size();
					pool.freePool -= record.size();
					
				}
				
		}
		
		
		else {		// the last page is added to the pool.
			Page page;
			try {
				page = storageManager.getLastPageOfTable(table);
			
				if( page.freeSpace > record.size() ){
					returnString = page.addRecord(record);
					
					int size = page.size();
					while(pool.freePool < size ){			// we free some space until there is enough to put the page where the record will be stored.
						Page freepage = pool.freeSpace();
						storageManager.store(freepage);
					}
					pool.addPage(page);		
				}
				else {
					int size = record.size();
					while(pool.freePool < size ){			// we free some space until there is enough to put the page where the record will be stored.
						Page freepage = pool.freeSpace();
						storageManager.store(freepage);
						}
					returnString = pool.addPage(record,table);
				}
			} 
			catch (IOException e) {
				e.printStackTrace();
			}
				
		}
		return returnString;		
	}
	
	public Record findData(RecordID recordID, Table table){	// returns the data from the table 'table' which have the recordID 'recordID' and null if the record is not found
		// First check if the page from the table is loaded in the pool
		Page page = pool.isPageOfTable(table, recordID.page);
		Record result;
		
		//If not loaded check that the page exist and load it
		if( (page == null) && (table.numberPages >= recordID.page)){
			page = storageManager.getPageOfTable(table, recordID.page);
		}
		
		// Check that the record number is smaller than the number of record in the page and returns the record		
		if(page == null || page.numberOfRecord < recordID.recordNumber)
			result = null;
		else{
			result = page.getRecord(recordID);
		}

		return result;
	}
	
	public Page getPageOfTable(Table table, int pageNumber){						// returns the page from the table and put it in the buffer if it wasn't
		Page returnPage = pool.isPageOfTable(table,pageNumber);
		if(returnPage == null){
			returnPage = storageManager.getPageOfTable(table,pageNumber);
			int size = returnPage.size();
			while(pool.freePool < size ){			// we free some space until there is enough to put the page.
				Page freepage = pool.freeSpace();
				storageManager.store(freepage);
				}
			pool.addPage(returnPage);
		}
		return returnPage;
	}
	
}